import csv
from decimal import Decimal
from datetime import datetime
from typing import List
from decimal import Decimal, ROUND_HALF_UP

from .row_data import RowData  # 假设你已有这个类

class RowDataCSVReader:
    def __init__(self, csv_path: str):
        self.csv_path = csv_path
        self._rows = self._load_rows()
        self._cursor = 0  # 当前读取位置

    def get_total_rows(self) -> int:
        """获取总行数"""
        return len(self._rows)

    def _parse_datetime_to_ms(self, date_str: str, time_str: str) -> int:
        """将 date+time 解析为毫秒级时间戳"""
        time_str = time_str.zfill(9)  # 9位：HHMMSSmmm
        dt_str = f"{date_str}{time_str[:6]}.{time_str[6:]}"  # yyyyMMddHHmmss.mmm
        dt = datetime.strptime(dt_str, "%Y%m%d%H%M%S.%f")
        return int(dt.timestamp() * 1000)

    def _load_rows(self) -> List[RowData]:
        """加载CSV文件并转换为 RowData 列表"""
        results = []
        with open(self.csv_path, newline='') as f:
            reader = csv.DictReader(f)
            for row in reader:
                timestamp_ms = self._parse_datetime_to_ms(row["date"], row["time"])
                symbol = row["symbol"]
                order_id = int(row["order_id"])
                price = (Decimal(row["price"]) / Decimal("10000")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) # 假设价格是整数 x1000
                quantity = int(row["quantity"])
                direction = row["direction"]  # B 或 S
                #根据op_code这一列判断是否是撤单，如果为D，则撤单，否则就不是撤单
                is_cancel = True if row.get("op_code", "") == "D" else False
                is_buy = True if direction == "B" else False
                results.append(RowData(symbol, timestamp_ms, order_id, price, quantity, is_buy, is_cancel))
        return results
    
    def read_before_930(self,) -> tuple[list[RowData], int]:
        """读取9点半之前的所有数据(不包含9点半)，并把 _cursor 移动到第一个 >= 9:30 的位置。"""
        results = []
    
        # 没有数据或已读完
        if not self._rows or self._cursor >= len(self._rows):
            return results
    
        # 从当前 cursor 行获取当天日期（如果 cursor 超出范围则退回到第0行）
        first_idx = self._cursor if self._cursor < len(self._rows) else 0
        first_timestamp_ms = self._rows[first_idx].get_timestamp_ms()
        today_date = datetime.fromtimestamp(first_timestamp_ms / 1000).date()
    
        # 9:30 的毫秒时间戳
        nine_thirty = datetime.combine(
            today_date, datetime.strptime("09:30:00", "%H:%M:%S").time()
        )
        nine_thirty_ms = int(nine_thirty.timestamp() * 1000)
    
        # 从 first_idx 开始读取直到第一个 >= 9:30 的行为止
        idx = first_idx
        while idx < len(self._rows) and self._rows[idx].get_timestamp_ms() < nine_thirty_ms:
            results.append(self._rows[idx])
            idx += 1
    
        # 将 cursor 移到停止位置（第一个 >=9:30 的行，或 len(self._rows)）
        self._cursor = idx
        return results, nine_thirty_ms


    def read_next_n_seconds(self, start_timestamp_ms: int, seconds: int) -> tuple[list[RowData], int, bool]:
        """
        从指定起始时间开始，读取未来 n 秒的数据。
        返回结果列表和实际结束时间戳（毫秒）。
        """
        if not self._rows:
            return [], start_timestamp_ms + seconds * 1000

        end_time = start_timestamp_ms + seconds * 1000
        result = []

        while self._cursor < len(self._rows):
            row = self._rows[self._cursor]
            ts = row.get_timestamp_ms()

            if ts < start_timestamp_ms:
                self._cursor += 1
                continue

            if ts > end_time:
                break

            result.append(row)
            self._cursor += 1

        #加一个判断，如果读取到末尾了给一个布尔值
        is_over: bool = False
        if self._cursor >= len(self._rows):
            is_over = True
        return result, end_time, is_over

    
    def get_current_position(self) -> int:
        """获取当前读取位置"""
        return self._cursor

    def read_between(self, start_ms: int, end_ms: int) -> List[RowData]:
        """读取两个毫秒时间戳之间的数据"""
        return [row for row in self._rows if start_ms <= row.get_timestamp_ms() <= end_ms]
    
    def reset(self):
        """重置读取位置"""
        self._cursor = 0
